package cn.fl.ref.fncprjbscinfo.util;

import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.cache.framework.utils.PropertiesCacheUtils;
import cn.fl.ref.fnccappayeeinfobig.vo.FncCapPayeeInfoBigVO;

public class PayeeBigUtil {
	private static final Logger logger = LoggerFactory.getLogger(PayeeBigUtil.class);
	
	//发送网银接口url
	private static final String URL = "fncbigpay.fncbigpay.properties.paybig.url";
	
	//封装请求参数
	public JSONObject  payBigParam(FncCapPayeeInfoBigVO fncCapPayeeInfoBigVO) {
		JSONObject jsonInfo = new JSONObject();
		
		jsonInfo.put("payeeId",fncCapPayeeInfoBigVO.getId());//付款流水号（付款收款方信息表的主键id，唯一标识。用于调用方查询放款记录使用
		jsonInfo.put("procInstCode",fncCapPayeeInfoBigVO.getpNo());//流程实例编号(如涉及流程流转，则必填，否则拜特付款成功后，流程不能继续向下流转)	C
		jsonInfo.put("payeeAcc",fncCapPayeeInfoBigVO.getAccNo());//	收款方账号	Y
		jsonInfo.put("payeeCorp",fncCapPayeeInfoBigVO.getRcptUnt());//	String	收款方名称	Y
		jsonInfo.put("payeeBank",fncCapPayeeInfoBigVO.getPayeeBkNm()) ;//	String	收款方银行	Y
		jsonInfo.put("payeeBankCode", fncCapPayeeInfoBigVO.getPayeeBkNo());//String	收款方银行号（fls与bfs预先约定）	Y
		BigDecimal num2 = new BigDecimal(100);
		BigDecimal payMoney = fncCapPayeeInfoBigVO.getPayAmt();
		payMoney=payMoney.multiply(num2);
		jsonInfo.put("payMoney",payMoney.longValue());//	Long	付款金额(单位：分)	Y
		jsonInfo.put("isQuick",  "0");//String	是否加急（1：加急 0：不加急）	Y
		if(0 == fncCapPayeeInfoBigVO.getPubPri()) {
			jsonInfo.put("purpose",fncCapPayeeInfoBigVO.getRcptUnt());//;//String	用途：对公传入省承租人；对私留空	C
		}
		jsonInfo.put("payType","1");	//String	付款方式	Y
		jsonInfo.put("isForIndividual",fncCapPayeeInfoBigVO.getPubPri())	;//String	对公对私（1:对私 0：对公）	Y
		jsonInfo.put("payerCorp", fncCapPayeeInfoBigVO.getPayer());//	String	付款方, 自动付款必填	C
		jsonInfo.put("payerAcc",fncCapPayeeInfoBigVO.getPayerAccNo());//String	付款方账号, 自动付款必填	C
		jsonInfo.put("payerBank",fncCapPayeeInfoBigVO.getPayerBkNm());//String	付款方银行, 自动付款必填	C
		jsonInfo.put("bifCode",fncCapPayeeInfoBigVO.getPayerBkNo());//String	付款方银行代码(我司与拜特预先预定) , 自动付款必填	C
		jsonInfo.put("cropCode",fncCapPayeeInfoBigVO.getCorpCode());//	String	单位编码	N
		jsonInfo.put("itemCode",fncCapPayeeInfoBigVO.getItemCode());//String 	预算科目	N
		jsonInfo.put("reserve1","1");//String	自动/手动放款 1自动，0手动	Y
		jsonInfo.put("reserve2","refinancing");//	String	操作标识:再融资-refinancing
		SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
		jsonInfo.put("wishPayDay",format2.format(new Date()));	//期望支付日期(YYYY-MM-DD)	N
		jsonInfo.put("payId",1l);//付款ID（业务表->付款表的主键ID）
		jsonInfo.put("projectId",1l);//项目ID（业务表->项目表的主键ID）	Y
		jsonInfo.put("projectNm","1");//	项目名称（业务表->项目表中的项目名称）	Y
		jsonInfo.put("payListCode","1");//	String	支付表编号（业务表->付款表的付款编号，一般格式为 <合同编号-*>）	Y
		jsonInfo.put("cstId",1l);//	Long	承租人编号	Y
		jsonInfo.put("cstNm", "1");	//String	承租人姓名	Y
		jsonInfo.put("cstBuOrgCd", "1");//	String	所属事业部编号	Y
		jsonInfo.put("cstBuOrgNm", "1");//	String	所属事业部名称	Y
		jsonInfo.put("cstMgrOrgCd", "1");//	String	所属分公司编号	Y
		jsonInfo.put("cstMgrOrgNm", "1");//	String	所属分公司名称	Y
		jsonInfo.put("procInstId", "1");
		jsonInfo.put("leaseCode", "1");
		jsonInfo.put("pId", "699630ED-9B0A-4850-AB83-DA79F91F473C");//	String	约定的项目CODE用于鉴权-服务方提供（请咨询接口提供方）	Y
		jsonInfo.put("bId", "D751E68A-8628-410E-8ACA-E3CC6EAB0448");//	String	约定的业务CODE用于鉴权-服务方提供（请咨询接口提供方）	Y
		
		BaseLogUtils.info(logger, "payBigParam", "进入大额付款发送网银接口==reqBody="+jsonInfo);
		return jsonInfo;
	}
	
	public static String PostHttpRequest( JSONObject params) throws Exception {
		Long startTm = System.currentTimeMillis();
		CloseableHttpClient client = HttpClients.createDefault();
		//超时时间
		int timeout = 50000;
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build();
		String result = null;
		try {
			String url=PropertiesCacheUtils.getProperty(URL);
			if(StringUtils.isNotBlank(url)){
				HttpPost request = new HttpPost(url);
				request.setHeader("Content-Type", "application/json;charset=UTF-8");
				request.setHeader("Accept", "application/json");
				request.setConfig(requestConfig);
				request.setEntity(new StringEntity(params.toString(), Charset.forName("UTF-8")));
				HttpResponse respones = client.execute(request);
				if (respones.getStatusLine().getStatusCode() == 200) {
					result = EntityUtils.toString(respones.getEntity(), "UTF-8");
				}else {
					BaseLogUtils.error(logger, null,"respones:"+respones);
				}
			}
		} catch (Exception e) {
			BaseLogUtils.error(logger, null,"PostHttpRequest异常:"+e.getMessage());
			e.printStackTrace();
			throw e;
		} finally {
			client.close();
		}
		 Long endTm = System.currentTimeMillis();
         BaseLogUtils.info(logger, "PostHttpRequest", "大额付款网银：" + (endTm - startTm) + "毫秒", "结果：" + result);
		return result;
	}
	 /**
     * 签名
     *
     * @param content
     * @param privateKey
     * @param charset
     * @methodName rsaSign
     * @author: hubo@lionbridgecapital.cn
     * @createDate: 2019/7/31 8:38 PM
     * @version: V1.0.0
     * @Return java.lang.String
     * @updateRemark [序号][YYYY-MM-DD] [更改人姓名][变更描述]
     */
    public String rsaSign(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8("RSA", privateKey);
            Signature signature = Signature.getInstance("SHA256WithRSA");
            signature.initSign(priKey);
            signature.update(content.getBytes(charset));

            byte[] signed = signature.sign();
            return new String(Base64.getEncoder().encodeToString(signed));
        } catch (InvalidKeySpecException e) {
            throw new Exception("RSA私钥格式不正确，请检查是否正确配置了PKCS8格式的私钥", e);
        } catch (Exception e) {
            throw new Exception("RSA content = " + content + "; charset = " + charset, e);
        }
    }

    private static PrivateKey getPrivateKeyFromPKCS8(String algorithm, String privateKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        byte[] encodedKey = Base64.getDecoder().decode(privateKey.getBytes("UTF-8"));
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }

    /**
     * 验签
     *
     * @param content
     * @param sign
     * @param publicKey
     * @param charset
     * @methodName rsaCheckContent
     * @author: hubo@lionbridgecapital.cn
     * @createDate: 2019/7/31 8:38 PM
     * @version: V1.0.0
     * @Return boolean
     * @updateRemark [序号][YYYY-MM-DD] [更改人姓名][变更描述]
     */
    public static  boolean rsaCheckContent(String content, String sign, String publicKey, String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509("RSA", publicKey);
            Signature signature = Signature.getInstance("SHA256WithRSA");
            signature.initVerify(pubKey);
            signature.update(content.getBytes(charset));

            return signature.verify(Base64.getDecoder().decode(sign.getBytes()));
        } catch (Exception var6) {
            throw new Exception("RSA content = " + content + ",sign=" + sign + ",charset = " + charset, var6);
        }
    }

    private static PublicKey getPublicKeyFromX509(String algorithm, String publicKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        byte[] encodedKey = Base64.getDecoder().decode(publicKey.getBytes("UTF-8"));
        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }
	
	
	
}
